/*
 * @Author: sparkstudiosju 419785598@qq.com
 * @Date: 2025-06-07 16:01:13
 * @LastEditors: sparkstudiosju 419785598@qq.com
 * @LastEditTime: 2025-06-07 16:18:32
 * @FilePath: \温度检测\ds18b20.c
 * @Description: 
 * 
 * Copyright (c) 2025 by ${git_name_email}, All Rights Reserved. 
 */
#include "ds18b20.h"

// DS18B20初始化函数 - 优化时序
unsigned char DS18B20_Init(void) {
    unsigned char presence = 1;
    
    DQ = 1;            // 拉高数据线
    delay_us(1);       // 短暂延时    
    DQ = 0;            // 发送复位脉冲
    delay_us(80);      // 延时80*12=960us (至少480us)    
    DQ = 1;            // 释放总线
    delay_us(8);       // 等待60us (15-60us之间读取存在脉冲)    
    presence = DQ;     // 读取存在脉冲
    delay_us(5);       // 完成存在脉冲时序 (总释放时间需大于480us)    
    return presence;   // 返回0表示检测到DS18B20，1表示未检测到
}

// DS18B20写一个字节 - 优化时序
void DS18B20_WriteByte(unsigned char dat) {
    unsigned char i = 0;
    for (i = 8; i > 0; i--) {
        DQ = 0;
        DQ = dat & 0x01;
        delay_us(4);
        DQ = 1;
        dat >>= 1;
    }
    delay_us(4);
}

// DS18B20读一个字节 - 优化时序
unsigned char DS18B20_ReadByte(void) {
    unsigned char i = 0;
    unsigned char dat = 0;
    for (i = 8; i > 0; i--) {
        DQ = 0;     // 拉低总线
        dat >>= 1;
        DQ = 1;     // 释放总线
        if(DQ)
            dat |= 0x80;
        delay_us(4);
    }
    return dat;
}

// DS18B20开始温度转换
void DS18B20_Start(void) {
    if(DS18B20_Init() == 0) {      // 初始化并检查DS18B20是否存在
        DS18B20_WriteByte(0xCC);   // 跳过ROM匹配
        DS18B20_WriteByte(0x44);   // 开始温度转换
    }
}

// DS18B20获取温度值 - 增加错误检查
float DS18B20_GetTemp(void) {
    unsigned char Temp_H = 0, Temp_L = 0;
    int raw = 0;
    float temp;

    if (DS18B20_Init()) return 1;
    //启动转换
    DS18B20_WriteByte(0xCC);  // Skip ROM
    DS18B20_WriteByte(0x44);  // Convert T
    delay_ms(750);        // Wait for conversion complete,about 750ms
    //初始化    
    if (DS18B20_Init()) return 2;
    //读取数据
    DS18B20_WriteByte(0xCC);  // Skip ROM
    DS18B20_WriteByte(0xBE);  // Read scratchpad

    Temp_L = DS18B20_ReadByte();   // LSB
    Temp_H = DS18B20_ReadByte();   // MSB

    raw = (Temp_H << 8) | Temp_L;

    if (raw < 0 || raw > 0x07D0) return 3;  // 0x07D0 = 2000
    //转换为温度值
    temp = (float)(raw * 0.0625);  // Convert to float Celsius
    return temp;
}

// 微秒延时函数
void delay_us(unsigned int us) {
    for(; us > 0; us--);  
}

// 毫秒延时函数
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = 0; i < ms; i++) {
        for(j = 0; j < 123; j++) {  // 12MHz下约1ms
            
        }
    }
} 

